package com.thoughtworks.testdox;
import com.thoughtworks.qdox.JavaDocBuilder;
import com.thoughtworks.qdox.model.JavaClass;
import com.thoughtworks.qdox.model.JavaMethod;
import com.thoughtworks.qdox.model.JavaSource;
import com.thoughtworks.testdox.ConsoleGenerator;
import com.thoughtworks.testdox.DocumentGenerator;
import com.thoughtworks.testdox.Generator;
import com.thoughtworks.testdox.Gui;
import javax.swing.*;
import java.io.File;
import java.io.IOException;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.io.PrintStream;
import java.io.FileOutputStream;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
/**
* Simple usage:
*/
public class Main implements Generator {
private static String usage = "Generate simple test documentation from JUnit source files\n"
+ "Usage: {0} [-txt text-output-file] [-html html-output-file] <source-directory>\n"
+ "\t<source-directory>: A source directory containing JUnit tests"
+ "\n"
+ "TestDox will generate documentation for test cases of the form *Test.java, *TestCase.java\n";
String directory;
private MultiplexingGenerator gen = new MultiplexingGenerator();
private NamePrettifier prettifier = new NamePrettifier();
public static JFrame gui;
private File inputFile;
public Main() {
gen.addGenerator(new ConsoleGenerator());
}
public void setTestDirectory(String directory) {
this.directory = directory;
}
public void addDocumentGenerator(DocumentGenerator generator) {
gen.addGenerator(generator);
}
public void parse() {
JavaDocBuilder builder = new JavaDocBuilder();
builder.addSourceTree(new File(directory));
JavaSource[] sources = builder.getSources();
if (sources.length < 1) {
throw new RuntimeException("No Source files found in directory "
+ directory);
}
doSources(sources);
}
void doSources(JavaSource[] sources) {
gen.startRun();
List<String> packagesStarted = new ArrayList<String>();
for (int i = 0; i < sources.length; i++) {
JavaSource source = sources[i];
JavaClass[] classes = source.getClasses();
doClasses(classes, source, packagesStarted);
}
gen.endGeneration();
gen.endRun();
}
void doClasses(JavaClass[] classes, JavaSource source,
List<String> packagesStarted) {
for (int j = 0; j < classes.length; j++) {
JavaClass aClass = classes[j];
if (isTestClass(aClass.getName())) {
String packageName = source.getPackage();
if (!packagesStarted.contains(packageName)) {
gen.startPackage(packageName);
packagesStarted.add(packageName);
}
String prettyName = prettifier.prettifyTestClass(aClass
.getName());
gen.startClass(prettyName);
doMethods(aClass.getMethods());
gen.endClass(prettyName);
}
}
}
/**
* TODO Needs to be generalised.
*/
boolean isTestClass(String className) {
return className.endsWith("Test") || className.endsWith("TestCase")
|| className.startsWith("Test")
|| className.endsWith("Behaviour");
}
private void doMethods(JavaMethod[] methods) {
for (int k = 0; k < methods.length; k++) {
String name = methods[k].getName();
if (prettifier.isATestMethod(name)) {
gen.onTest(prettifier.prettifyTestMethod(name));
}
}
}
public static void main(String[] args) {
Main main = new Main();
try {
main.processArguments(args);
} catch (Throwable e) {
e.printStackTrace();
}
}
private static void showUsage() {
String message = MessageFormat.format(usage, new String[] { Main.class
.getName() });
System.err.println(message);
}
public void generate() {
try {
setTestDirectory(inputFile.getCanonicalPath());
parse();
} catch (IOException e) {
e.printStackTrace();
}
}
public void addGenerator(DocumentGenerator generator) {
gen.addGenerator(generator);
}
public void reset() {
gen.clear();
}
/**
* TODO check for what conditions help is printed
*
* @param args
* @throws IOException
*/
public void processArguments(String[] args) throws IOException {
if (args.length == 0) {
gui = new Gui("Test Docs", this);
gui.show();
return;
}
for (int i = 0; i < args.length; i++) {
String arg = args[i];
if (arg.equals("--help") || arg.equals("-h")) {
showUsage();
return;
} else if (arg.equals("-txt")) {
i++;
checkParameterExists(args, i,
"Expected a fileName to follow the -txt argument");
PrintStream out = new PrintStream(new FileOutputStream(
new File(args[i]), true));
ConsoleGenerator textGenerator = new ConsoleGenerator(out);
gen.addGenerator(textGenerator);
} else if (arg.equals("-html")) {
i++;
checkParameterExists(args, i,
"Expected a fileName to follow the -html argument");
PrintWriter out = new PrintWriter(new FileWriter(new File(
args[i]), true));
HtmlDocumentGenerator htmlGenerator = new HtmlDocumentGenerator(
out);
gen.addGenerator(htmlGenerator);
} else {
checkParameterExists(args, i,
"Expected a fileName to follow the -txt argument");
setInputFile(new File(args[i]));
}
}
if (inputFile == null) {
throw new RuntimeException("Expected an inputFile");
}
generate();
}
private void checkParameterExists(String[] args, int i, String message) {
if (args.length < i) {
throw new RuntimeException("Too few arguments: " + message);
}
}
public void setInputFile(File file) {
this.inputFile = file;
}
}